#include <algorithm>
#include "image_drawer.h"

NAMESPACE_START

// 8x8 的ASCII 字符集，方便字符转点阵
// https://blog.csdn.net/MoXianSheng/article/details/52193243?utm_source=distribute.pc_relevant.none-task

static const uint8_t font8x8ext[] =
{
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E,
    0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E,
    0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00,
    0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00,
    0x38, 0x7C, 0x38, 0xFE, 0xFE, 0xD6, 0x10, 0x38,
    0x10, 0x38, 0x7C, 0xFE, 0xFE, 0x7C, 0x10, 0x38,
    0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00,
    0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF,
    0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00,
    0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF,
    0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78,
    0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18,
    0x3F, 0x33, 0x3F, 0x30, 0x30, 0x70, 0xF0, 0xE0,
    0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0,
    0x18, 0xDB, 0x3C, 0xE7, 0xE7, 0x3C, 0xDB, 0x18,
    0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00,
    0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00,
    0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18,
    0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00,
    0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00,
    0x3E, 0x61, 0x3C, 0x66, 0x66, 0x3C, 0x86, 0x7C,
    0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00,
    0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF,
    0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00,
    0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00,
    0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00,
    0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00,
    0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00,
    0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00,
    0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00,
    0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00,
    0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00,
    0x18, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0x18, 0x00,
    0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00,
    0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00,
    0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x0C, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00,
    0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00,
    0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00,
    0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
    0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
    0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00,
    0x7C, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0x7C, 0x00,
    0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00,
    0x7C, 0xC6, 0x06, 0x1C, 0x30, 0x66, 0xFE, 0x00,
    0x7C, 0xC6, 0x06, 0x3C, 0x06, 0xC6, 0x7C, 0x00,
    0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00,
    0xFE, 0xC0, 0xC0, 0xFC, 0x06, 0xC6, 0x7C, 0x00,
    0x38, 0x60, 0xC0, 0xFC, 0xC6, 0xC6, 0x7C, 0x00,
    0xFE, 0xC6, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00,
    0x7C, 0xC6, 0xC6, 0x7C, 0xC6, 0xC6, 0x7C, 0x00,
    0x7C, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0x78, 0x00,
    0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00,
    0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
    0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00,
    0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00,
    0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00,
    0x7C, 0xC6, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00,
    0x7C, 0xC6, 0xDE, 0xDE, 0xDE, 0xC0, 0x78, 0x00,
    0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00,
    0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00,
    0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00,
    0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00,
    0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00,
    0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00,
    0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3A, 0x00,
    0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00,
    0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00,
    0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00,
    0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00,
    0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00,
    0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00,
    0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00,
    0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00,
    0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00,
    0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xCE, 0x7C, 0x0E,
    0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00,
    0x7C, 0xC6, 0x60, 0x38, 0x0C, 0xC6, 0x7C, 0x00,
    0x7E, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x3C, 0x00,
    0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00,
    0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00,
    0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x00,
    0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 0x00,
    0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x3C, 0x00,
    0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00,
    0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00,
    0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00,
    0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 0x00,
    0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
    0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
    0xE0, 0x60, 0x7C, 0x66, 0x66, 0x66, 0xDC, 0x00,
    0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x00,
    0x1C, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
    0x00, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0x7C, 0x00,
    0x3C, 0x66, 0x60, 0xF8, 0x60, 0x60, 0xF0, 0x00,
    0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
    0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00,
    0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00,
    0x06, 0x00, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C,
    0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00,
    0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00,
    0x00, 0x00, 0xEC, 0xFE, 0xD6, 0xD6, 0xD6, 0x00,
    0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x00,
    0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00,
    0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0,
    0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E,
    0x00, 0x00, 0xDC, 0x76, 0x60, 0x60, 0xF0, 0x00,
    0x00, 0x00, 0x7E, 0xC0, 0x7C, 0x06, 0xFC, 0x00,
    0x30, 0x30, 0xFC, 0x30, 0x30, 0x36, 0x1C, 0x00,
    0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
    0x00, 0x00, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00,
    0x00, 0x00, 0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x00,
    0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00,
    0x00, 0x00, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0xFC,
    0x00, 0x00, 0x7E, 0x4C, 0x18, 0x32, 0x7E, 0x00,
    0x0E, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0E, 0x00,
    0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
    0x70, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x70, 0x00,
    0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00,
    0x60, 0xF0, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x0C,
    0xFC, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x6C, 0x00,
    0x1C, 0x10, 0x00, 0x7E, 0x60, 0x60, 0x60, 0x00,
    0x38, 0x20, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0x00,
    0x6C, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0x7C, 0x00,
    0x6C, 0xFE, 0x62, 0x78, 0x60, 0x62, 0xFE, 0x00,
    0x00, 0x00, 0x7C, 0xC6, 0xF0, 0xC6, 0x7C, 0x00,
    0x3C, 0x66, 0xC0, 0xF8, 0xC0, 0x66, 0x3C, 0x00,
    0x00, 0x00, 0x7E, 0xC0, 0x7C, 0x06, 0xFC, 0x00,
    0x7C, 0xC6, 0x60, 0x38, 0x0C, 0xC6, 0x7C, 0x00,
    0x30, 0x00, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
    0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
    0xCC, 0x00, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
    0x66, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00,
    0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x70,
    0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0xCC, 0x78, 0x00,
    0x00, 0x00, 0x70, 0x50, 0x5C, 0x52, 0xDC, 0x00,
    0x70, 0x50, 0x5C, 0x52, 0x52, 0x52, 0xDC, 0x00,
    0x00, 0x00, 0xA0, 0xA0, 0xFC, 0xA2, 0xBC, 0x00,
    0xA0, 0xA0, 0xA0, 0xFC, 0xA2, 0xA2, 0xBC, 0x00,
    0x60, 0xF0, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x00,
    0xF8, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x00,
    0x1C, 0x10, 0xC6, 0xD8, 0xF8, 0xCC, 0xC6, 0x00,
    0x18, 0xD6, 0xCC, 0xF8, 0xF8, 0xCC, 0xC6, 0x00,
    0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x7C,
    0x38, 0xC6, 0xC6, 0x7E, 0x06, 0xC6, 0x7C, 0x00,
    0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0x10,
    0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0x10,
    0x00, 0x00, 0xDC, 0xD6, 0xF6, 0xD6, 0xDC, 0x00,
    0xDC, 0xD6, 0xD6, 0xF6, 0xD6, 0xD6, 0xDC, 0x00,
    0x00, 0x00, 0xF0, 0xB0, 0x3C, 0x36, 0x3C, 0x00,
    0xF0, 0xF0, 0xB0, 0x3C, 0x36, 0x36, 0x3C, 0x00,
    0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
    0x3E, 0x66, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0x00,
    0x06, 0x7C, 0xC0, 0x7C, 0xC6, 0xC6, 0x7C, 0x00,
    0xFE, 0x66, 0x60, 0x7C, 0x66, 0x66, 0xFC, 0x00,
    0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xFE, 0x06,
    0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFE, 0x06,
    0x00, 0x00, 0x3C, 0x6C, 0x6C, 0x6C, 0xFE, 0xC6,
    0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3,
    0x00, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0x7C, 0x00,
    0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00,
    0x00, 0x00, 0x7C, 0xD6, 0xD6, 0x7C, 0x10, 0x38,
    0x7C, 0xD6, 0xD6, 0xD6, 0x7C, 0x10, 0x38, 0x00,
    0x00, 0x00, 0xFE, 0x66, 0x60, 0x60, 0xF0, 0x00,
    0xFE, 0x66, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00,
    0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00,
    0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00,
    0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,
    0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
    0xDB, 0x77, 0xDB, 0xEE, 0xDB, 0x77, 0xDB, 0xEE,
    0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
    0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18,
    0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00,
    0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 0x00,
    0x00, 0x00, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0x00,
    0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0x00,
    0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36,
    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
    0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36,
    0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00,
    0x00, 0x38, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0x00,
    0x38, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0x00,
    0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18,
    0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00,
    0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18,
    0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18,
    0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
    0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18,
    0x00, 0x00, 0xE6, 0x6C, 0x78, 0x6C, 0xE6, 0x00,
    0xE6, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00,
    0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36,
    0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00,
    0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36,
    0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36,
    0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00,
    0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36,
    0x00, 0xC6, 0x7C, 0xC6, 0xC6, 0x7C, 0xC6, 0x00,
    0x00, 0x00, 0x3E, 0x66, 0x66, 0x66, 0xE6, 0x00,
    0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xC6, 0x00,
    0x00, 0x00, 0xC6, 0xFE, 0xFE, 0xD6, 0xC6, 0x00,
    0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00,
    0x00, 0x00, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0x00,
    0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00,
    0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00,
    0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00,
    0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00,
    0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00,
    0x00, 0x00, 0x7E, 0xC6, 0x7E, 0x66, 0xC6, 0x00,
    0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
    0x7E, 0xC6, 0xC6, 0xC6, 0x7E, 0x66, 0xC6, 0x00,
    0x00, 0x00, 0xFC, 0x66, 0x66, 0x7C, 0x60, 0xF0,
    0xFC, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xF0, 0x00,
    0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x00,
    0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00,
    0x00, 0x00, 0x7E, 0x5A, 0x18, 0x18, 0x3C, 0x00,
    0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00,
    0x00, 0x00, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x7C,
    0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0xC6, 0x7C, 0x00,
    0x00, 0x00, 0xD6, 0x7C, 0x38, 0x7C, 0xD6, 0x00,
    0xD6, 0xD6, 0x7C, 0x38, 0x7C, 0xD6, 0xD6, 0x00,
    0x00, 0x00, 0xFC, 0x66, 0x7C, 0x66, 0xFC, 0x00,
    0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00,
    0x00, 0x00, 0xF0, 0x60, 0x7C, 0x66, 0xFC, 0x00,
    0xF0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00,
    0x8F, 0xCD, 0xEF, 0xFC, 0xDC, 0xCC, 0xCC, 0x00,
    0x00, 0x00, 0x00, 0x7C, 0x7C, 0x00, 0x00, 0x00,
    0x00, 0x00, 0xC6, 0xC6, 0xF6, 0xDE, 0xF6, 0x00,
    0xC6, 0xC6, 0xC6, 0xF6, 0xDE, 0xDE, 0xF6, 0x00,
    0x00, 0x00, 0x7C, 0xC6, 0x1C, 0xC6, 0x7C, 0x00,
    0x7C, 0xC6, 0x06, 0x3C, 0x06, 0xC6, 0x7C, 0x00,
    0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00,
    0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00,
    0x00, 0x00, 0x7C, 0xC6, 0x1E, 0xC6, 0x7C, 0x00,
    0x78, 0x8C, 0x06, 0x3E, 0x06, 0x8C, 0x78, 0x00,
    0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xFF, 0x03,
    0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFF, 0x03,
    0x00, 0x00, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x00,
    0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x00,
    0x3E, 0x61, 0x3C, 0x66, 0x66, 0x3C, 0x86, 0x7C,
    0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// ================================================




// forward declaration ----
static void DrawingText8( const std::shared_ptr<const Image>& src, const std::string& text, int32_t x, int32_t y, Argb color, Argb background );
static void XDrawingText24( const std::shared_ptr<const Image>& src, const std::string& text, int32_t x, int32_t y, Argb color, Argb background );
// ------------------------

// 
Error ImageDrawer::HLine( const std::shared_ptr<const Image>& image, int32_t x1, int32_t x2, int32_t y, Argb color )
{
    Error  ret = Error::Success;

    if ( ( !image ) || ( image->Data() == nullptr ) )
    {
        ret = Error::NullPointer;
    }/* 检查图片数据格式 */
    else if ( ( image->Format( ) != PixelFormat::Grayscale8 ) &&
              ( image->Format( ) != PixelFormat::RGB24 ) &&
              ( image->Format( ) != PixelFormat::RGBA32 ) )
    {
        ret = Error::UnsupportedPixelFormat;
    }
    else
    {
        if ( ( y >= 0 ) && ( y < image->Height( ) ) && ( color.components.a != 0 ) )
        {
            //获取行的长度
            int stride = image->Stride( );
            int left   = std::min( x1, x2 );
            int right  = std::max( x1, x2 );
            int x;

            uint8_t fillA       = color.components.a;
            float   fillAlpha   = 0;
            float   fill1mAlpha = 0;
            //检查数值进行，均一化处理
            if ( fillA != 255 )
            {
                fillAlpha   = static_cast<float>( fillA ) / 255.0f;
                //计算原来的通道透明度
                fill1mAlpha = 1.0f - fillAlpha;
            }
            //计算指针
            uint8_t* ptr = image->Data( ) + y * stride;

            left  = std::max( 0, left );
            right = std::min( image->Width( ) - 1, right );

            if ( image->Format( ) == PixelFormat::Grayscale8 )
            {
                uint8_t fillValue = static_cast<uint8_t>( RGB_TO_GRAY( color.components.r, color.components.g, color.components.b ) );

                ptr += left;

                if ( fillA == 255 )
                {
                    // 全透明度，无需处理，直接填充
                    for ( x = left; x <= right; x++ )
                    {
                        *ptr = fillValue;
                        ptr++;
                    }
                }
                else
                {
                    float fillValueA = fillAlpha * fillValue;

                    //做填充处理
                    for ( x = left; x <= right; x++ )
                    {
                        *ptr = static_cast<uint8_t>( fillValueA + ( *ptr * fill1mAlpha ) );
                        ptr++;
                    }

                }
            }
            else
            {
                uint8_t fillR     = color.components.r;
                uint8_t fillG     = color.components.g;
                uint8_t fillB     = color.components.b;
                int     pixelSize = ( image->Format( ) == PixelFormat::RGB24 ) ? 3 : 4;

                ptr += left * pixelSize;

                // 注意：对于32 bpp 的图像，我们保持其alpha不变，不考虑alpha混合
                /*
                https://blog.csdn.net/wyq1153/article/details/53959410
                */
                if ( fillA == 255 )
                {
                    for ( x = left; x <= right; x++ )
                    {
                        ptr[RedIndex]   = fillR;
                        ptr[GreenIndex] = fillG;
                        ptr[BlueIndex]  = fillB;
                        ptr            += pixelSize;
                    }
                }
                else
                {
                    float fillRA = fillAlpha * fillR;
                    float fillGA = fillAlpha * fillG;
                    float fillBA = fillAlpha * fillB;

                    // 执行通道混合，这里的混合算法有待改进
                    /*
                    https://www.cnblogs.com/oloroso/p/10724803.html
                    */
                    for ( x = left; x <= right; x++ )
                    {
                        ptr[RedIndex]   = static_cast<uint8_t>( fillRA + ( ptr[RedIndex]   * fill1mAlpha ) );
                        ptr[GreenIndex] = static_cast<uint8_t>( fillGA + ( ptr[GreenIndex] * fill1mAlpha ) );
                        ptr[BlueIndex]  = static_cast<uint8_t>( fillBA + ( ptr[BlueIndex]  * fill1mAlpha ) );
                        ptr            += pixelSize;
                    }
                }
            }
        }
    }

    return ret;
}

// 垂直数据更改
Error ImageDrawer::VLine( const std::shared_ptr<const Image>& image, int32_t y1, int32_t y2, int32_t x, Argb color )
{
    Error  ret = Error::Success;

    if ( ( !image ) || ( image->Data( ) == nullptr ) )
    {
        ret = Error::NullPointer;
    }
    else if ( ( image->Format( ) != PixelFormat::Grayscale8 ) &&
              ( image->Format( ) != PixelFormat::RGB24 ) &&
              ( image->Format( ) != PixelFormat::RGBA32 ) )
    {
        ret = Error::UnsupportedPixelFormat;
    }
    else
    {
        if ( ( x >= 0 ) && ( x < image->Width( ) ) )
        {
            int stride = image->Stride( );
            int top    = std::min( y1, y2 );
            int bottom = std::max( y1, y2 );
            int y;

            uint8_t fillA       = color.components.a;
            float   fillAlpha   = 0;
            float   fill1mAlpha = 0;

            if ( fillA != 255 )
            {
                fillAlpha   = static_cast<float>( fillA / 255.0f );
                fill1mAlpha = 1.0f - fillAlpha;
            }

            uint8_t* ptr = image->Data( );

            top    = std::max( 0, top );
            bottom = std::min( image->Height( ) - 1, bottom );

            ptr += top * stride;

            if ( image->Format( ) == PixelFormat::Grayscale8 )
            {
                uint8_t fillValue = static_cast<uint8_t>( RGB_TO_GRAY( color.components.r, color.components.g, color.components.b ) );

                ptr += x;

                if ( fillA == 255 )
                {
                    // the fill color has no transparency, so just fill
                    for ( y = top; y <= bottom; y++ )
                    {
                        *ptr = fillValue;
                        ptr += stride;
                    }
                }
                else
                {
                    float fillValueA = fillAlpha * fillValue;

                    // do alpha blending
                    for ( y = top; y <= bottom; y++ )
                    {
                        *ptr = static_cast<uint8_t>( fillValueA + ( *ptr * fill1mAlpha ) );
                        ptr += stride;
                    }
                }
            }
            else
            {
                uint8_t fillR     = color.components.r;
                uint8_t fillG     = color.components.g;
                uint8_t fillB     = color.components.b;
                int     pixelSize = ( image->Format( ) == PixelFormat::RGB24 ) ? 3 : 4;

                ptr += x * pixelSize;

                // NOTE: for 32 bpp images we leave their alpha as is and don't take it into account for alpha blending

                if ( fillA == 255 )
                {
                    // the fill color has no transparency, so just fill
                    for ( y = top; y <= bottom; y++ )
                    {
                        ptr[RedIndex]   = fillR;
                        ptr[GreenIndex] = fillG;
                        ptr[BlueIndex]  = fillB;
                        ptr += stride;
                    }
                }
                else
                {
                    float fillRA = fillAlpha * fillR;
                    float fillGA = fillAlpha * fillG;
                    float fillBA = fillAlpha * fillB;

                    // do alpha blending
                    for ( y = top; y <= bottom; y++ )
                    {
                        ptr[RedIndex]   = static_cast<uint8_t>( fillRA + ( ptr[RedIndex]   * fill1mAlpha ) );
                        ptr[GreenIndex] = static_cast<uint8_t>( fillGA + ( ptr[GreenIndex] * fill1mAlpha ) );
                        ptr[BlueIndex]  = static_cast<uint8_t>( fillBA + ( ptr[BlueIndex]  * fill1mAlpha ) );
                        ptr += stride;
                    }
                }
            }
        }
    }

    return ret;
}

// 更改指定范围内的值
Error ImageDrawer::Rectangle( const std::shared_ptr<const Image>& image, int32_t x1, int32_t y1, int32_t x2, int32_t y2, Argb color )
{
    Error  ret = Error::Success;

    if ( ( !image ) || ( image->Data( ) == nullptr ) )
    {
        ret = Error::NullPointer;
    }
    else if ( ( image->Format( ) != PixelFormat::Grayscale8 ) &&
              ( image->Format( ) != PixelFormat::RGB24 ) &&
              ( image->Format( ) != PixelFormat::RGBA32 ) )
    {
        ret = Error::UnsupportedPixelFormat;
    }
    else
    {
        ImageDrawer::HLine( image, x1, x2, y1, color );
        ImageDrawer::HLine( image, x1, x2, y2, color );

        ImageDrawer::VLine( image, y1 + 1, y2 - 1, x1, color );
        ImageDrawer::VLine( image, y1 + 1, y2 - 1, x2, color );
    }

    return ret;
}

// 在图像的指定位置绘制ASCII文本，将ASCII转化为点阵图，添加到图片上
Error ImageDrawer::PutText( const std::shared_ptr<const Image>& image, const std::string& text, int32_t x, int32_t y, Argb color, Argb background, bool addBorder )
{
    Error  ret = Error::Success;

    if ( ( !image ) || ( image->Data( ) == nullptr ) )
    {
        ret = Error::NullPointer;
    }
    else if ( ( image->Format( ) != PixelFormat::Grayscale8 ) &&
              ( image->Format( ) != PixelFormat::RGB24 ) &&
              ( image->Format( ) != PixelFormat::RGBA32 ) )
    {
        ret = Error::UnsupportedPixelFormat;
    }
    else
    {
        int32_t len        = static_cast<int32_t>( text.length( ) );
        int32_t borderSize = ( addBorder ) ? 2 : 0;
        int32_t b;

        // do nothing if ...
        if ( ( len != 0 ) &&                                                       // if nothing to print
            ( y + 8 + borderSize * 2 > 0 ) && ( y < image->Height( ) ) &&          // if text is out in Y direction
            ( x + 8 * len + borderSize * 2 > 0 ) && ( x < image->Width( ) ) &&     // if text is out in X direction
            ( ( color.components.a != 0 ) || ( background.components.a != 0 ) ) )  // if it is all transparent
        {
            for ( b = 0; b < borderSize; b++ )
            {
                ImageDrawer::Rectangle( image, x + b, y + b, x + len * 8 + borderSize * 2 - b - 1, y + 8 + borderSize * 2 - b - 1, background );
            }

            x += borderSize;
            y += borderSize;

            // re-check coordinates without border
            if ( ( y + 8 > 0 ) && ( y < image->Height( ) ) &&          // if text is out in Y direction
                 ( x + 8 * len > 0 ) && ( x < image->Width( ) ) )      // if text is out in X direction
            {
                if ( image->Format( ) == PixelFormat::Grayscale8 )
                {
                    DrawingText8( image, text, x, y, color, background );
                }
                else
                {
                    XDrawingText24( image, text, x, y, color, background );
                }
            }
        }
    }

    return ret;
}

// 8位灰度图像，字符填充，使用1字节字符串，进行直接进行颜色设置，范围值在0~255
void DrawingText8(
        const std::shared_ptr<const Image>& src, 
        const std::string& text, 
        int32_t x, /* 填充宽度 */
        int32_t y, /* 填充高度 */
        Argb color, 
        Argb background
    )
{
    /* 获取图片的基本信息 */
    int         width       = src->Width( );
    int         height      = src->Height( );
    int         stride      = src->Stride( );
    int         yOffset     = ( y >= 0 ) ? 0 : -y;
    int         endY        = ( y + 8 <= height ) ? 8 : height - y;
    /* 开始地址指针 */
    uint8_t*    basePtr     = src->Data( ) + y * stride + x;

    /* 前景填充 */
    uint8_t     textValue   = static_cast<uint8_t>( RGB_TO_GRAY( color.components.r, color.components.g, color.components.b ) );
    uint8_t     textA       = color.components.a;
    
    float       textAlpha   = static_cast<float>( textA ) / 255.0f;
    float       textmAlpha = 1.0f - textAlpha;
    float       textValueA  = textAlpha * textValue;
    
    /* 背景填充  */
    uint8_t     bgValue     = static_cast<uint8_t> RGB_TO_GRAY( background.components.r, background.components.g, background.components.b );
    uint8_t     bgA         = background.components.a;
    float       bgAlpha     = static_cast<float>( bgA ) / 255.0f;
    float       bg1mAlpha   = 1.0f - bgAlpha;
    float       bgValueA    = bgAlpha * bgValue;
    /* 字符串值指针 */
    const char* textPtr     = text.c_str( );

    while ( *textPtr )
    {
        if ( x >= width )
        {
            break;
        }

        if ( x > -8 )
        {
            //获取字符串对应的16进制颜色值指针数组
            const uint8_t* symbolPtr = &( font8x8ext[*textPtr * 8] );
            //计算偏移
            int      xOffset = ( x >= 0 ) ? 0 : -x;
            //计算掩码
            uint8_t  mask    = 1 << ( 7 - xOffset );
            //设置遍历变量
            int      sx, sy, tx;
            //按照列来进行填充
            for ( sy = yOffset; sy < endY; sy++ )
            {
                uint8_t  tempMask   = mask;
                //获取对应的偏移值
                uint8_t  symbolLine = symbolPtr[sy];
                uint8_t* imagePtr   = basePtr + sy * stride + xOffset;
                //行
                for ( sx = xOffset, tx = x + xOffset; ( sx < 8 ) && ( tx < width ); sx++, tx++ )
                {
                    //检查是否需要对位上的数据进行更改
                    if ( symbolLine & tempMask )
                    {
                        if ( textA == 255 )
                        {
                            *imagePtr = textValue;
                        }
                        else
                        {
                            *imagePtr = static_cast<uint8_t>( textValueA + ( *imagePtr * textmAlpha ) );
                        }
                    }
                    else
                    {
                        if ( bgA == 255 )
                        {
                            *imagePtr = bgValue;
                        }
                        else
                        {
                            *imagePtr = static_cast<uint8_t>( bgValueA + ( *imagePtr * bg1mAlpha ) );
                        }
                    }
                    //检查下一个数据
                    tempMask >>= 1;
                    imagePtr++;
                }
            }
        }
        //更新x的位置
        x       += 8;
        basePtr += 8;
        textPtr++;
    }
}

// Draw the specified text on 24/32 bpp color images
void XDrawingText24( const std::shared_ptr<const Image>& src, const std::string& text, int32_t x, int32_t y, Argb color, Argb background )
{
    int         width       = src->Width( );
    int         height      = src->Height( );
    int         stride      = src->Stride( );
    int         yOffset     = ( y >= 0 ) ? 0 : -y;
    int         endY        = ( y + 8 <= height ) ? 8 : height - y;
    int         pixelSize   = ( src->Format( ) == PixelFormat::RGB24 ) ? 3 : 4;
    uint8_t*    basePtr     = src->Data( ) + y * stride + x * pixelSize;

    uint8_t     textR       = color.components.r;
    uint8_t     textG       = color.components.g;
    uint8_t     textB       = color.components.b;
    uint8_t     textA       = color.components.a;
    float       textAlpha   = static_cast<float>( textA ) / 255.0f;
    float       textmAlpha = 1.0f - textAlpha;
    float       textRA      = textAlpha * textR;
    float       textGA      = textAlpha * textG;
    float       textBA      = textAlpha * textB;

    uint8_t     bgR         = background.components.r;
    uint8_t     bgG         = background.components.g;
    uint8_t     bgB         = background.components.b;
    uint8_t     bgA         = background.components.a;
    float       bgAlpha     = static_cast<float>( bgA ) / 255.0f;
    float       bg1mAlpha   = 1.0f - bgAlpha;
    float       bgRA        = bgAlpha * bgR;
    float       bgGA        = bgAlpha * bgG;
    float       bgBA        = bgAlpha * bgB;

    const char* textPtr     = text.c_str( );

    while ( *textPtr )
    {
        if ( x >= width )
        {
            break;
        }

        if ( x > -8 )
        {
            const uint8_t* symbolPtr = &( font8x8ext[*textPtr * 8] );

            int      xOffset = ( x >= 0 ) ? 0 : -x;
            uint8_t  mask    = 1 << ( 7 - xOffset );
            int      sx, sy, tx;

            for ( sy = yOffset; sy < endY; sy++ )
            {
                uint8_t  tempMask   = mask;
                uint8_t  symbolLine = symbolPtr[sy];
                uint8_t* imagePtr   = basePtr + sy * stride + xOffset * pixelSize;

                for ( sx = xOffset, tx = x + xOffset; ( sx < 8 ) && ( tx < width ); sx++, tx++ )
                {
                    if ( symbolLine & tempMask )
                    {
                        if ( textA == 255 )
                        {
                            imagePtr[RedIndex]   = textR;
                            imagePtr[GreenIndex] = textG;
                            imagePtr[BlueIndex]  = textB;
                        }
                        else
                        {
                            imagePtr[RedIndex]   = (uint8_t) ( textRA + ( imagePtr[RedIndex]   * textmAlpha ) );
                            imagePtr[GreenIndex] = (uint8_t) ( textGA + ( imagePtr[GreenIndex] * textmAlpha ) );
                            imagePtr[BlueIndex]  = (uint8_t) ( textBA + ( imagePtr[BlueIndex]  * textmAlpha ) );
                        }
                    }
                    else
                    {
                        if ( bgA == 255 )
                        {
                            imagePtr[RedIndex]   = bgR;
                            imagePtr[GreenIndex] = bgG;
                            imagePtr[BlueIndex]  = bgB;
                        }
                        else
                        {
                            imagePtr[RedIndex]   = (uint8_t) ( bgRA + ( imagePtr[RedIndex]   * bg1mAlpha ) );
                            imagePtr[GreenIndex] = (uint8_t) ( bgGA + ( imagePtr[GreenIndex] * bg1mAlpha ) );
                            imagePtr[BlueIndex]  = (uint8_t) ( bgBA + ( imagePtr[BlueIndex]  * bg1mAlpha ) );
                        }
                    }

                    tempMask >>= 1;
                    imagePtr  += pixelSize;
                }
            }
        }

        x       += 8;
        basePtr += ( 8 * pixelSize );
        textPtr++;
    }
}

// rgb(24/32)图像填充
void DrawingText24( const std::shared_ptr<const Image>& src, const std::string& text, int32_t x, int32_t y, Argb color, Argb background )
{
    int         width       = src->Width( );
    int         height      = src->Height( );
    int         stride      = src->Stride( );

    int         yOffset     = ( y >= 0 ) ? 0 : -y;
    int         endY        = ( y + 8 <= height ) ? 8 : height - y;
    /* 获取字节大小 */
    int         pixelSize   = ( src->Format( ) == PixelFormat::RGB24 ) ? 3 : 4;

    uint8_t*    basePtr     = src->Data( ) + y * stride + x * pixelSize;

    uint8_t     textR       = color.components.r;
    uint8_t     textG       = color.components.g;
    uint8_t     textB       = color.components.b;
    uint8_t     textA       = color.components.a;

    float       textAlpha   = static_cast<float>( textA ) / 255.0f;
    float       textmAlpha = 1.0f - textAlpha;
    float       textRA      = textAlpha * textR;
    float       textGA      = textAlpha * textG;
    float       textBA      = textAlpha * textB;

    uint8_t     bgR         = background.components.r;
    uint8_t     bgG         = background.components.g;
    uint8_t     bgB         = background.components.b;
    uint8_t     bgA         = background.components.a;
    float       bgAlpha     = static_cast<float>( bgA ) / 255.0f;
    float       bg1mAlpha   = 1.0f - bgAlpha;
    float       bgRA        = bgAlpha * bgR;
    float       bgGA        = bgAlpha * bgG;
    float       bgBA        = bgAlpha * bgB;

    const char* textPtr     = text.c_str( );
    //将颜色全部拷贝进去
    while ( *textPtr )
    {
        if ( x >= width )
        {
            break;
        }

        if ( x > -8 )
        {
            const uint8_t* symbolPtr = &( font8x8ext[*textPtr * 8] );

            int      xOffset = ( x >= 0 ) ? 0 : -x;
            uint8_t  mask    = 1 << ( 7 - xOffset );
            int      sx, sy, tx;

            for ( sy = yOffset; sy < endY; sy++ )
            {
                
                uint8_t  tempMask   = mask;
                uint8_t  symbolLine = symbolPtr[sy];
                uint8_t* imagePtr   = basePtr + sy * stride + xOffset * pixelSize;

                for ( sx = xOffset, tx = x + xOffset; ( sx < 8 ) && ( tx < width ); sx++, tx++ )
                {
                    if ( symbolLine & tempMask )
                    {
                        if ( textA == 255 )
                        {
                            imagePtr[RedIndex]   = textR;
                            imagePtr[GreenIndex] = textG;
                            imagePtr[BlueIndex]  = textB;
                        }
                        else
                        {
                            imagePtr[RedIndex]   = (uint8_t) ( textRA + ( imagePtr[RedIndex]   * textmAlpha ) );
                            imagePtr[GreenIndex] = (uint8_t) ( textGA + ( imagePtr[GreenIndex] * textmAlpha ) );
                            imagePtr[BlueIndex]  = (uint8_t) ( textBA + ( imagePtr[BlueIndex]  * textmAlpha ) );
                        }
                    }
                    else
                    {
                        if ( bgA == 255 )
                        {
                            imagePtr[RedIndex]   = bgR;
                            imagePtr[GreenIndex] = bgG;
                            imagePtr[BlueIndex]  = bgB;
                        }
                        else
                        {
                            imagePtr[RedIndex]   = (uint8_t) ( bgRA + ( imagePtr[RedIndex]   * bg1mAlpha ) );
                            imagePtr[GreenIndex] = (uint8_t) ( bgGA + ( imagePtr[GreenIndex] * bg1mAlpha ) );
                            imagePtr[BlueIndex]  = (uint8_t) ( bgBA + ( imagePtr[BlueIndex]  * bg1mAlpha ) );
                        }
                    }

                    tempMask >>= 1;
                    imagePtr  += pixelSize;
                }
            }
        }

        x       += 8;
        basePtr += ( 8 * pixelSize );
        textPtr++;
    }
}



NAMESPACE_END